﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using Sector7.Framework.Enums;
using Sector7.Framework.Utility;
using System.Windows.Controls;
using System.Windows.Input;
using System.Reflection;
using Sector7.Framework.Consts;

namespace Sector7.Framework.Core
{
    /// <summary>
    /// 添加模式窗口基类
    /// </summary>
    public class AddModeWindowBase : BizWindowBase
    {
        #region NEED implementation in subclass
        /// <summary>
        /// 获取或设置窗口实体信息
        /// </summary>
        public virtual object Entity
        {
            get { return m_entity; }
            set { m_entity = value; }
        }

        /// <summary>
        /// 初始化窗口
        /// </summary>
        /// <param name="crud">窗口操作类型</param>
        public virtual void InitializeWindow(CrudType crud)
        {
            GetData();

            m_crud = crud;

            string prefix = string.Empty;
            switch (m_crud)
            {
                case CrudType.Create:
                    prefix = "新建";
                    InitializeForCreating();
                    break;
                case CrudType.Update:
                    prefix = "修改";
                    InitializeForUpdating();
                    break;
                default:
                    break;
            }

            InitializeForOthers();

            this.Title = string.Format("{0}{1}", prefix, this.Title);
            this.DataContext = m_entity;
        }

        /// <summary>
        /// 为新建功能初始化
        /// </summary>
        protected virtual void InitializeForCreating()
        {
        }

        /// <summary>
        /// 为修改功能初始化
        /// </summary>
        protected virtual void InitializeForUpdating()
        {
            m_originalEntity = ReflectionUtil.InvokePrivateMethod(m_entity, C_FunctionName.MEMBERWISE_CLONE);
        }

        /// <summary>
        /// 初始化窗口其他控件或变量
        /// </summary>
        protected virtual void InitializeForOthers()
        {
            if (FocusedControl != null)
            {
                FocusedControl.Focus();
            }
        }

        /// <summary>
        /// 值自动增长
        /// </summary>
        protected virtual void AutoAdd() { }

        /// <summary>
        /// 检查数据有效性（默认总是返回true）
        /// </summary>
        /// <returns>检查结果</returns>
        protected virtual bool CheckData()
        {
            return m_errors.Count == 0;
        }

        /// <summary>
        /// 获取数据改变量
        /// </summary>
        /// <param name="primaryKey">主键属性名称</param>
        /// <param name="isChanged">返回是否有改变量</param>
        /// <returns>数据改变量</returns>
        public virtual EntityDeltaBase GetDelta(string primaryKey, ref bool isChanged)
        {
            EntityDeltaBase delta = ClientUtil.CreateDelta<EntityDeltaBase>(m_originalEntity.GetType());

            delta.Conditions.Add(primaryKey, ReflectionUtil.GetPropertyValue(m_originalEntity, primaryKey));

            PropertyInfo[] properties = ReflectionUtil.GetProperties(m_originalEntity);
            foreach (PropertyInfo property in properties)
            {
                string propertyName = property.Name;

                //if ((!m_excludeProperties.Contains(propertyName)) && !(property.PropertyType.BaseType == typeof(EntityBase)))
                if (ReflectionUtil.IsContainAttribute(m_originalEntity, propertyName, typeof(DBFieldAttribute)))
                {
                    object currentValue = ReflectionUtil.GetPropertyValue(m_entity, propertyName);
                    object originalValue = ReflectionUtil.GetPropertyValue(m_originalEntity, propertyName);

                    if ((currentValue == null && originalValue != null)
                        || (currentValue != null && !currentValue.Equals(originalValue)))
                    {
                        delta.DeltaProperties.Add(propertyName, currentValue);
                    }
                }
            }

            isChanged = delta.DeltaProperties.Count > 0;

            return delta;
        }

        /// <summary>
        /// 添加数据
        /// </summary>
        /// <returns></returns>
        protected virtual void AddData()
        {
            OnAddSuccess(new EventArgs());
        }

        /// <summary>
        /// 获取数据
        /// </summary>
        protected virtual void GetData() { }

        /// <summary>
        /// 快捷键 Ctrl + O：执行打开功能
        /// </summary>
        protected virtual void DoOpen() { }

        /// <summary>
        /// 快捷键 Ctrl + N：执行新建功能
        /// </summary>
        protected virtual void DoNew() { }

        /// <summary>
        /// 快捷键 Ctrl + I：执行导入功能
        /// </summary>
        protected virtual void DoImport() { }

        /// <summary>
        /// 快捷键 ContextMenu - 编辑：执行修改操作
        /// </summary>
        protected virtual void DoModify() { }

        /// <summary>
        /// 快捷键 ContextMenu - 删除：执行删除炒作
        /// </summary>
        protected virtual void DoDelete() { }

        /// <summary>
        /// 点击继续按钮事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void btnContinue_Click(object sender, RoutedEventArgs e)
        {
            DoAddAndContinue();
        }

        /// <summary>
        /// 点击确定按钮事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void btnOk_Click(object sender, RoutedEventArgs e)
        {
            DoAddAndExit();
        }

        /// <summary>
        /// 点击取消按钮事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            DoCancel();
        }
        #endregion

        #region NO NEED change anything in subclass

        /// <summary>
        /// 初始化添加模式窗口
        /// </summary>
        public AddModeWindowBase()
        {
            this.ResizeMode = ResizeMode.NoResize;
            this.ShowInTaskbar = false;
            this.WindowStartupLocation = WindowStartupLocation.CenterOwner;
            this.Initialized += new EventHandler(AddModeWindowBase_Initialized);
            this.KeyDown += new KeyEventHandler(AddModeWindowBase_KeyDown);

            m_excludeProperties.Add("ExtensionData");
        }

        /// <summary>
        /// 添加成功事件
        /// </summary>
        public event EventHandler AddSuccess = null;

        /// <summary>
        /// 获取窗口操作类型
        /// </summary>
        public CrudType Crud
        {
            get { return m_crud; }
        }

        /// <summary>
        /// 获取自动增长值
        /// </summary>
        public string AddedValue
        {
            get
            {
                if (m_addValue > 0)
                {
                    return string.Format(m_addValueFormat, m_addValue);
                }
                else
                {
                    return string.Empty;
                }
            }
        }

        /// <summary>
        /// 重置窗口
        /// </summary>
        public void ResetWindow()
        {
            AutoAdd();

            switch (m_crud)
            {
                case CrudType.Create:
                    InitializeForCreating();
                    break;
                case CrudType.Update:
                    InitializeForUpdating();
                    break;
                default:
                    break;
            }

            InitializeForOthers();
        }

        /// <summary>
        /// 排除检查数据改变量的属性名称
        /// </summary>
        private List<string> m_excludeProperties = new List<string>();

        /// <summary>
        /// 显示错误信息
        /// </summary>
        protected void ShowErrors()
        {
            if (m_errors.Count > 0)
            {
                StringBuilder errors = new StringBuilder();
                foreach (KeyValuePair<string, string> kvp in m_errors)
                {
                    errors.Append(string.Format("{0}: {1}\n", kvp.Key, kvp.Value));
                }

                Alert.ShowDialog(AlertType.Error, errors.ToString());
            }
        }

        /// <summary>
        /// 触发添加成功事件
        /// </summary>
        /// <param name="e"></param>
        protected void OnAddSuccess(EventArgs e)
        {
            if (AddSuccess != null)
                AddSuccess(this, e);
        }

        /// <summary>
        /// 窗口初始化完成时发生
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void AddModeWindowBase_Initialized(object sender, EventArgs e)
        {
            this.Owner = Senvironments.MainWindow;
        }

        /// <summary>
        /// 窗口按键按下时发生
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void AddModeWindowBase_KeyDown(object sender, KeyEventArgs e)
        {
            if ((e.KeyboardDevice.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
            {
                switch (e.Key)
                {
                    case Key.Enter:
                        if (m_enableShortcut)
                            DoAddAndExit();
                        break;
                    case Key.O:
                        DoOpen();
                        break;
                    case Key.N:
                        DoNew();
                        break;
                    default:
                        break;
                }
            }
            else
            {
                switch (e.Key)
                {
                    case Key.Enter:
                        if (m_enableShortcut)
                            DoAddAndContinue();
                        break;
                    case Key.Delete:
                        DoDelete();
                        break;
                    default:
                        break;
                }
            }
        }

        /// <summary>
        /// 快捷键 Esc：执行退出功能
        /// </summary>
        protected void DoCancel()
        {
            this.DialogResult = false;
        }

        /// <summary>
        /// 快捷键 Ctrl + Enter：执行添加并退出功能
        /// </summary>
        protected void DoAddAndExit()
        {
            if (CheckData())
            {
                AddData();

                if (m_isAddSuccess)
                {
                    this.DialogResult = true;
                }
            }
            else
            {
                ShowErrors();
            }
        }

        /// <summary>
        /// 快捷键 Ctrl：执行添加并继续功能
        /// </summary>
        protected void DoAddAndContinue()
        {
            if (m_crud == CrudType.Create)
            {
                if (CheckData())
                {
                    AddData();

                    if (m_isAddSuccess)
                    {
                        ResetWindow();
                    }
                }
                else
                {
                    ShowErrors();
                }
            }
        }

        /// <summary>
        /// 窗口操作类型
        /// </summary>
        protected CrudType m_crud = CrudType.Unknown;

        /// <summary>
        /// 窗口数据
        /// </summary>
        protected object m_entity = null;

        /// <summary>
        /// 窗口原始数据
        /// </summary>
        protected object m_originalEntity = null;

        /// <summary>
        /// 自动增长值
        /// </summary>
        protected int m_addValue = 0;

        /// <summary>
        /// 自动增长表示格式
        /// </summary>
        protected string m_addValueFormat = "{0}";

        /// <summary>
        /// 激活窗口快捷键
        /// </summary>
        protected bool m_enableShortcut = true;

        /// <summary>
        /// 是否添加成功标志
        /// </summary>
        protected bool m_isAddSuccess = false;

        /// <summary>
        /// 错误信息字典（key - 控件或变量名称； value - 错误信息）
        /// </summary>
        protected Dictionary<string, string> m_errors = new Dictionary<string, string>();

        #endregion
    }
}